/*
 * @Descripttion:
 * @version:
 * @Author: gengzhi
 * @Date: 2020-08-14 09:58:08
 * @LastEditors: gengzhi
 * @LastEditTime: 2020-08-18 15:32:18
 */
package presentation

import (
	"context"
	"kendoDDD/crossutting/memoryBus"
	"kendoDDD/ddd_application"
	"kendoDDD/dddcore"
)

type HttpServer interface {
	DispatchCommand(context.Context, string, []byte) (string, error)
	DispatchCommandMap(context.Context, string, map[string]string) (string, error)
}

var kendoHttpSer HttpServer

type httpServer struct {
	commandBus dddcore.CommandBus
	eventBus   dddcore.EventBus
	eventStore dddcore.EventStore
}

func init() {
	eventStore := memoryBus.NewEventStore()
	eventBus := memoryBus.NewEventBus()
	commandBus := memoryBus.NewCommandBus()

	kendoHttpSer = newHttpServer(commandBus, eventBus, eventStore)
}

func (s *httpServer) DispatchCommand(ctx context.Context, command string, payload []byte) (string, error) {
	out := make(chan dddcore.BusChan)
	defer close(out)

	go func() {
		s.commandBus.Publish(ctx, command, payload, out)
	}()

	select {
	case <-ctx.Done():
		return "ctx.Done了", ctx.Err()
	case msg, _ := <-out:
		return msg.RespMsg, msg.ErrMsg
	}
	return "", nil
}

func (s *httpServer) DispatchCommandMap(ctx context.Context, command string, payload map[string]string) (string, error) {
	out := make(chan dddcore.BusChan)
	defer close(out)

	go func() {
		s.commandBus.Publish(ctx, command, payload, out)
	}()

	select {
	case <-ctx.Done():
		return "ctx.Done了", ctx.Err()
	case msg, _ := <-out:
		return msg.RespMsg, msg.ErrMsg
	}
}

func newHttpServer(cb dddcore.CommandBus, eb dddcore.EventBus, es dddcore.EventStore) HttpServer {
	s := &httpServer{cb, eb, es}
	registerHttpCommandHandlers(cb, es, eb)
	registerHttpEventHandlers(eb)
	return s

}

func registerHttpCommandHandlers(cb dddcore.CommandBus, es dddcore.EventStore, eb dddcore.EventBus) {
	cb.Subscribe(SingnProtocolByInfo, ddd_application.OnSingnProtocol(es, eb))
	cb.SubscribeMap(CfmProtocolByReqSn, ddd_application.OnCfrmProtocol(es, eb))
	cb.SubscribeMap(GetProtocolInfoByNo, ddd_application.OnGetProtocolByNo(es, eb))
	cb.SubscribeMap(GetWSTokenByUser, ddd_application.OnGetWsToken(es, eb))
}

func registerHttpEventHandlers(es dddcore.EventBus) {

}
